package org.fujay.langchain4jserver.infrastructure.adapter.langchain;

import cn.hutool.core.collection.CollUtil;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.fujay.commons.langchain4j.param.ChatMode;
import org.fujay.commons.langchain4j.param.ChatParam;
import org.fujay.commons.langchain4j.param.Message;
import org.fujay.commons.langchain4j.server.ChatService;
import org.fujay.commons.langchain4j.server.MultiService;
import org.fujay.langchain4jserver.domain.application.entity.App;
import org.fujay.langchain4jserver.domain.conversation.aggregate.ConversationAggregate;
import org.fujay.langchain4jserver.domain.conversation.entity.MessageEntity;
import org.fujay.langchain4jserver.domain.conversation.service.ConversationProcessor;
import org.fujay.langchain4jserver.domain.model.aggregate.Model;
import org.fujay.langchain4jserver.domain.model.service.ModelProviderService;
import org.springframework.stereotype.Component;
import reactor.core.publisher.Flux;

import java.util.Collections;
import java.util.List;
import java.util.function.Consumer;

/**
 * 对话处理器适配器，集成 commons-langchain4j
 */
@Slf4j
@Component
@RequiredArgsConstructor
public class ChatAdapter implements ConversationProcessor {

    private final ChatService chatService;
    private final MultiService multiService;
    private final ModelProviderService modelProviderService;

    @Override
    public Flux<Message> generateResponse(
            MessageEntity userMessage,
            ConversationAggregate conversation,
            App app,
            Model model,
            Consumer<Message> doOnComplete) {

        log.info(
                "处理模型对话: {}, App: {}, Model: {}",
                conversation.getId().value(),
                app.getId().value(),
                model.getId().id());

        // 构造chatParam ---
        ChatParam param = new ChatParam();
        param.setUserId(String.valueOf(conversation.getUserId().value()));
        param.setMemoryId(conversation.getMemoryId());
        param.setUserMessage(userMessage.getContent());
        param.setDoOnComplete(doOnComplete);
        // fixme 系统提示词功能待实现
        // param.setSystemMessage(...);

        List<String> imageUrls =
                userMessage.getImageUrls() != null ? userMessage.getImageUrls() : Collections.emptyList();
        param.setUrl(imageUrls);
        // 设置流式对话模型和向量模型
        param.setStreamingChatModel(
                modelProviderService.getStreamingChatModel(model));

        Flux<Message> responseFlux;

        try {
            if (CollUtil.isNotEmpty(imageUrls)) {
                log.info("多模态对话: {}. 图片数量: {}", conversation.getId().value(), imageUrls.size());
                responseFlux = multiService.multimodalChat(param);

            } else {
                log.info("检测到的仅文本请求进行对话: {}.", conversation.getId().value());
                boolean useRag = app.isUseKnowledgeBase();
                if(useRag){
                    param.setEmbeddingModel(modelProviderService.getEmbeddingModel(model));
                    param.setChatMode(ChatMode.RAG);
                }
                log.info("对话模式: {}", param.getChatMode());
                responseFlux = chatService.chat(param);
            }
            return responseFlux;

        } catch (Exception e) {
            log.error(
                    "Failed to generate response for conversation: {}, error: {}",
                    conversation.getId().value(),
                    e.getMessage(),
                    e);
            throw e;
        }
    }
}
